﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace Panels
{
    public class SimpleWrapPanel : Panel
    {
        public SimpleWrapPanel()
        { }

        protected override Size MeasureOverride(Size availableSize)
        {
            // We will now measure our panel and also the requested size of our children.
            // The returned size is used by the layout system e.g. to give a scrollviewer
            // a true size of the children.

            // First check if a height and width is set.
            Size maxSize = new Size();
            maxSize.Width = double.IsNaN(this.Width) ? availableSize.Width : this.Width;
            maxSize.Height = double.IsNaN(this.Height) ? availableSize.Height : this.Height;

            Size newSize = new Size();
            Size currentSize = new Size();

            foreach (UIElement child in this.Children)
            {
                child.Measure(maxSize);
                Size childSize = child.DesiredSize;

                if (double.IsInfinity(maxSize.Width))
                {
                    newSize.Width += childSize.Width;
                    newSize.Height = Math.Max(newSize.Height, childSize.Height);
                }
                else
                {
                    if ((currentSize.Width + childSize.Width) <= maxSize.Width)
                    {
                        // We are within the bounds, just register the size of the child.
                        currentSize.Width += childSize.Width;
                        currentSize.Height = Math.Max(currentSize.Height, childSize.Height);
                    }
                    else
                    {
                        // We have reached the end of a row. Register the size and move
                        // to the next row.
                        newSize.Width = Math.Max(newSize.Width, currentSize.Width);
                        newSize.Height += currentSize.Height;

                        currentSize.Width = childSize.Width;
                        currentSize.Height = childSize.Height;
                    }
                }
            }

            return newSize;
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            // Position our elements in the panel.

            double maxHeight = 0.0;
            Point position = new Point(0.0, 0.0);

            foreach (UIElement child in this.Children)
            {
                Size childSize = child.DesiredSize;

                if ((position.X + childSize.Width) > finalSize.Width)
                {
                    position.X = 0.0;
                    position.Y += maxHeight;
                    maxHeight = 0.0;
                }

                child.Arrange(new Rect(position.X, position.Y, childSize.Width, childSize.Height));

                position.X += childSize.Width;
                maxHeight = Math.Max(childSize.Height, maxHeight);
            }

            return finalSize;
        }
    }
}
